package com.ouc.oceanBase.controller;


import com.ouc.common.config.properties.ApplicationProperties;
import com.ouc.common.core.controller.BaseController;
import com.ouc.common.core.domain.AjaxResult;
import com.ouc.common.entity.FlowData;
import com.ouc.common.entity.NcData;
import com.ouc.common.entity.NcGridData;
import com.ouc.common.entity.NcRecord;
import com.ouc.common.ncRead.NcDao;
import com.ouc.common.ncRead.impl.NcDaoImpl;
import com.ouc.common.utils.Arith;
import com.ouc.common.utils.ArrayUtils;
import com.ouc.common.utils.DateUtils;
import com.ouc.common.utils.MathUtils;
import com.ouc.common.utils.file.FileUtils;
import com.ouc.dataMange.domain.Upload;
import com.ouc.dataMange.service.CopernicusService;
import com.ouc.dataMange.service.ISysDataSetService;
import com.ouc.dataMange.service.ISysMemoryDeviceService;
import com.ouc.oceanBase.entity.ContourData;
import com.ouc.oceanBase.entity.FactorCondition;
import com.ouc.oceanBase.entity.FlowGridData;
import com.ouc.oceanBase.entity.PictFile;
import com.ouc.oceanBase.service.EddyCharacterService;
import com.ouc.oceanBase.service.FactorService;
import com.ouc.oceanBase.service.NcPictService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import ucar.ma2.InvalidRangeException;
import ucar.nc2.NetcdfFile;

import java.io.File;
import java.io.IOException;
import java.util.*;
import java.util.concurrent.ExecutionException;

import static com.ouc.common.constant.NcConstants.*;

/**
 * @author B504
 */
@RestController
@CrossOrigin
@RequestMapping("/factor")
public class FactorController extends BaseController {

  @Autowired
  private ApplicationProperties appPro;

  @Autowired
  private EddyCharacterService eddyCharacterService;

  @Autowired
  private NcDao ncDao;

  @Autowired
  private CopernicusService uploadService;

  @Autowired
  private ISysMemoryDeviceService memoryDeviceService;

  @Autowired
  private ISysDataSetService dataSetService;

  @Autowired
  private NcPictService ncPictService;

  @Autowired
  ApplicationProperties applicationProperties;

//  @Autowired
//  ProfileService profileService;

  @Autowired
  FactorService factorService;

  //  这行注释之前都是龙哥写的接口，之后是自己写的接口

  /**
   * 从nc文件生成图片
   *
   * @param filePath        nc文件路径
   * @param factorCondition 要素参数
   * @param fixedMin        给予的最大值 如果给予的是NaN则使用二维数据自动的最大值
   * @param fixedMax        给予的最小值 如果给予的是NaN则使用二维数据自动的最大值
   * @param colorType       颜色类型有blackbody，cooltowarm，grayscale，rainbow
   * @return
   */
  @RequestMapping("/getPictFromPath")
//  @Log(title = "nc文件可视化", businessType = BusinessType.DRAW, isSaveResponseData = false)
  public AjaxResult getPictFromPath(@RequestParam("filePath") String filePath,
                                    FactorCondition factorCondition,
                                    @RequestParam("fixedMin") float fixedMin,
                                    @RequestParam("fixedMax") float fixedMax,
                                    @RequestParam("colorType") String colorType,
                                    @RequestParam(value = "time", required = false) Integer time,
                                    @RequestParam(value = "reverseFlag", required = false, defaultValue = "false") boolean reverseFlag) {
    return getPict(filePath, factorCondition, fixedMin, fixedMax, colorType, time, reverseFlag);
  }

  /**
   * 从nc文件生成图片(预报数据)
   *
   * @param factorCondition 要素参数
   * @param fixedMin        给予的最大值 如果给予的是NaN则使用二维数据自动的最大值
   * @param fixedMax        给予的最小值 如果给予的是NaN则使用二维数据自动的最大值
   * @param colorType       颜色类型有blackbody，cooltowarm，grayscale，rainbow
   * @return
   */
  @RequestMapping("/getPictFromPathByForecast")
//  @Log(title = "nc文件可视化", businessType = BusinessType.DRAW, isSaveResponseData = false)
  public AjaxResult getPictFromPathByForecast(FactorCondition factorCondition,
                                              @RequestParam("fixedMin") float fixedMin,
                                              @RequestParam("fixedMax") float fixedMax,
                                              @RequestParam("colorType") String colorType,
                                              @RequestParam(value = "time", required = false) String time,
                                              @RequestParam(value = "ncTime", required = false) String ncTime,
                                              @RequestParam(value = "reverseFlag", required = false, defaultValue = "false") boolean reverseFlag) {
//    return getPict(filePath, factorCondition, fixedMin, fixedMax, colorType, time, reverseFlag);
    String variableName = factorCondition.getVariableName();
    if (variableName.equals("so")) {
      String filePath = "D:\\mydatabase\\forecastdata\\" + time + "\\so_" + ncTime + ".nc";
      return getPict(filePath, factorCondition, fixedMin, fixedMax, colorType, null, reverseFlag);
    }
    if (variableName.equals("sst")) {
      String filePath = "D:\\mydatabase\\forecastdata\\" + time + "\\sst_" + ncTime + ".nc";
      return getPict(filePath, factorCondition, fixedMin, fixedMax, colorType, null, reverseFlag);
    }
    if (variableName.equals("wo")) {
      String filePath = "D:\\mydatabase\\forecastdata\\" + time + "\\wo_" + ncTime + ".nc";
      return getPict(filePath, factorCondition, fixedMin, fixedMax, colorType, null, reverseFlag);
    }
    if (variableName.equals("zos")) {
      String filePath = "D:\\mydatabase\\forecastdata\\" + time + "\\zos_" + ncTime + ".nc";
      return getPict(filePath, factorCondition, fixedMin, fixedMax, colorType, null, reverseFlag);
    }
    return AjaxResult.error("变量名称错误");
  }

  /**
   * 获取有经纬度限制的粒子流(预报数据）
   *
   * @param factorCondition 要素条件
   * @return
   */
  @RequestMapping(value = "getParticleFlowByLimitByForecast")
//  @Log(title = "流场粒子流可视化", businessType = BusinessType.DRAW, isSaveResponseData = false)
  @ResponseBody
  public AjaxResult getParticleFlowByLimitByForecast(FactorCondition factorCondition,
                                                     @RequestParam(value = "time", required = false) String time,
                                                     @RequestParam(value = "ncTime", required = false) String ncTime,
                                                     @RequestParam(value = "dilution") int dilution,
                                                     @RequestParam(value = "exaggerate") int exaggerate) {

    Integer t = null;
    String filePath = "D:\\mydatabase\\forecastdata\\" + time + "\\uovo_" + ncTime + ".nc";
    try (NetcdfFile ncFile = NetcdfFile.open(filePath)) {
      FlowData uu = factorService.getParticleFlowDataOfFlowByLimit(ncFile, factorCondition.getStartLon(), factorCondition.getEndLon(),
          factorCondition.getStartLat(), factorCondition.getEndLat(), factorCondition.getLevel(), t, UU, dilution, exaggerate, true, false);
      FlowData vv = factorService.getParticleFlowDataOfFlowByLimit(ncFile, factorCondition.getStartLon(), factorCondition.getEndLon(),
          factorCondition.getStartLat(), factorCondition.getEndLat(), factorCondition.getLevel(), t, VV, dilution, exaggerate, true, false);
      List<Float> data = new ArrayList<>();
      for (int i = 0; i < uu.getData().size(); i++) {
        if (uu.getData().get(i) != null || vv.getData().get(i) != null) {
          if ((float) Arith.round(Math.sqrt(Math.pow(uu.getData().get(i), 2) + Math.pow(vv.getData().get(i), 2)), 4) > 150) {
          }
          data.add((float) Arith.round(Math.sqrt(Math.pow(uu.getData().get(i), 2) + Math.pow(vv.getData().get(i), 2)), 4));
        } else {
          data.add(0f);
        }
      }
      Object[] objects = {uu, vv, data};
      return AjaxResult.success(objects);
    } catch (Exception e) {
      e.printStackTrace();
      return AjaxResult.error("获取nc文件失败");
    }
  }


  /**
   * 获取有经纬度限制的粒子流
   *
   * @param filePath        nc文件绝对路径
   * @param factorCondition 要素条件
   * @return
   */
  @RequestMapping(value = "getParticleFlowByLimit")
//  @Log(title = "流场粒子流可视化", businessType = BusinessType.DRAW, isSaveResponseData = false)
  @ResponseBody
  public AjaxResult getParticleFlowByLimit(@RequestParam("filePath") String filePath,
                                           FactorCondition factorCondition,
                                           @RequestParam(value = "time", required = false) Integer time,
                                           @RequestParam(value = "dilution") int dilution,
                                           @RequestParam(value = "exaggerate") int exaggerate) {
    try (NetcdfFile ncFile = NetcdfFile.open(filePath)) {
      FlowData uu = factorService.getParticleFlowDataOfFlowByLimit(ncFile, factorCondition.getStartLon(), factorCondition.getEndLon(),
          factorCondition.getStartLat(), factorCondition.getEndLat(), factorCondition.getLevel(), time, UU, dilution, exaggerate, true, false);
      FlowData vv = factorService.getParticleFlowDataOfFlowByLimit(ncFile, factorCondition.getStartLon(), factorCondition.getEndLon(),
          factorCondition.getStartLat(), factorCondition.getEndLat(), factorCondition.getLevel(), time, VV, dilution, exaggerate, true, false);
      List<Float> data = new ArrayList<>();
      for (int i = 0; i < uu.getData().size(); i++) {
        if (uu.getData().get(i) != null || vv.getData().get(i) != null) {
          if ((float) Arith.round(Math.sqrt(Math.pow(uu.getData().get(i), 2) + Math.pow(vv.getData().get(i), 2)), 4) > 150) {
          }
          data.add((float) Arith.round(Math.sqrt(Math.pow(uu.getData().get(i), 2) + Math.pow(vv.getData().get(i), 2)), 4));
        } else {
          data.add(0f);
        }
      }
      Object[] objects = {uu, vv, data};
      return AjaxResult.success(objects);
    } catch (Exception e) {
      e.printStackTrace();
      return AjaxResult.error("获取nc文件失败");
    }
  }

  /**
   * 获取有经纬度限制的粒子流，返回原始数据，不再处理
   *
   * @param filePath        nc文件绝对路径
   * @param factorCondition 要素条件
   * @return
   */
  @RequestMapping(value = "getParticleFlowByLimitNew")
//  @Log(title = "流场粒子流可视化", businessType = BusinessType.DRAW, isSaveResponseData = false)
  @ResponseBody
  public AjaxResult getParticleFlowByLimitNew(@RequestParam("filePath") String filePath,
                                              FactorCondition factorCondition,
                                              @RequestParam(value = "time", required = false) Integer time,
                                              @RequestParam(value = "variableName1", required = false, defaultValue = "uo") String variableName1,
                                              @RequestParam(value = "variableName2", required = false, defaultValue = "vo") String variableName2) {
    try (NetcdfFile ncFile = NetcdfFile.open(filePath)) {
      Map<String, NcData> ncDataOfLimitU = ncDao.getNcDataOfLimitFromVariable(ncFile, variableName1, new Float[]{factorCondition.getStartLon(), factorCondition.getEndLon()},
          new Float[]{factorCondition.getStartLat(), factorCondition.getEndLat()}, factorCondition.getLevel(), time);
      Map<String, NcData> ncDataOfLimitV = ncDao.getNcDataOfLimitFromVariable(ncFile, variableName2, new Float[]{factorCondition.getStartLon(), factorCondition.getEndLon()},
          new Float[]{factorCondition.getStartLat(), factorCondition.getEndLat()}, factorCondition.getLevel(), time);
      Object[] objects = {ncDataOfLimitU, ncDataOfLimitV};
      return AjaxResult.success(objects);
    } catch (Exception e) {
      e.printStackTrace();
      return AjaxResult.error("获取nc文件失败");
    }
  }


  /**
   * 获取有经纬度限制的风场粒子流
   *
   * @param filePath        nc文件绝对路径
   * @param factorCondition 要素条件
   * @return
   */
  @RequestMapping(value = "getParticleFlowByLimitWind")
  @ResponseBody
//  @Log(title = "风场粒子流可视化", businessType = BusinessType.DRAW, isSaveResponseData = false)
  public AjaxResult getParticleFlowByLimitWind(@RequestParam("filePath") String filePath,
                                               FactorCondition factorCondition,
                                               @RequestParam(value = "time", required = false) Integer time,
                                               @RequestParam(value = "dilution") int dilution,
                                               @RequestParam(value = "exaggerate") int exaggerate) {
    try (NetcdfFile ncFile = NetcdfFile.open(filePath)) {
      FlowData uu = factorService.getParticleFlowDataOfFlowByLimit(ncFile, factorCondition.getStartLon(), factorCondition.getEndLon(),
          factorCondition.getStartLat(), factorCondition.getEndLat(), factorCondition.getLevel(), time, UU, dilution, exaggerate, false, false);
      FlowData vv = factorService.getParticleFlowDataOfFlowByLimit(ncFile, factorCondition.getStartLon(), factorCondition.getEndLon(),
          factorCondition.getStartLat(), factorCondition.getEndLat(), factorCondition.getLevel(), time, VV, dilution, exaggerate, false, false);
      List<Float> data = new ArrayList<>();
      for (int i = 0; i < uu.getData().size(); i++) {
        if (uu.getData().get(i) != null || vv.getData().get(i) != null) {
          data.add((float) Arith.round(Math.sqrt(Math.pow(uu.getData().get(i), 2) + Math.pow(vv.getData().get(i), 2)), 4));
        } else {
          data.add(0f);
        }
      }
      Object[] objects = {uu, vv, data};
      return AjaxResult.success(objects);
    } catch (Exception e) {
      e.printStackTrace();
      return AjaxResult.error("获取nc文件失败");
    }
  }

  /**
   * 后台测试前台勿使用
   *
   * @param filePath        nc文件路径
   * @param factorCondition 参数设置
   * @param dilution        稀释倍数
   * @param exaggerate      夸张倍数
   * @return
   */
  @RequestMapping(value = "getParticleFlowByLimit1")
  @ResponseBody
  public AjaxResult getParticleFlowByLimit1(@RequestParam("filePath") String filePath,
                                            FactorCondition factorCondition,
                                            int dilution,
                                            int exaggerate) {
    try (NetcdfFile ncFile = NetcdfFile.open(filePath)) {
      FlowData uu = factorService.getParticleFlowDataOfFlowByLimit1(ncFile, factorCondition.getStartLon(), factorCondition.getEndLon(),
          factorCondition.getStartLat(), factorCondition.getEndLat(), factorCondition.getLevel(), UU, dilution, exaggerate);
      FlowData vv = factorService.getParticleFlowDataOfFlowByLimit1(ncFile, factorCondition.getStartLon(), factorCondition.getEndLon(),
          factorCondition.getStartLat(), factorCondition.getEndLat(), factorCondition.getLevel(), VV, dilution, exaggerate);
      List<Float> data = new ArrayList<>();
      for (int i = 0; i < uu.getData().size(); i++) {
        if (uu.getData().get(i) != null || vv.getData().get(i) != null) {
          data.add((float) Arith.round(Math.sqrt(Math.pow(uu.getData().get(i), 2) + Math.pow(vv.getData().get(i), 2)), 4));
        } else {
          data.add(0f);
        }
      }

      Float[] floats = MathUtils.minAndMax(data);
      System.out.println("Arrays.toString(floats) = " + Arrays.toString(floats));
      Object[] objects = {uu, vv, data};
      return AjaxResult.success(objects);
    } catch (Exception e) {
      e.printStackTrace();
      return AjaxResult.error("获取nc文件失败");
    }
  }

  /**
   * 获取一整层数据的粒子流
   * 待改进（边界值有问题）
   *
   * @param filePath   文件路径
   * @param level      层级
   * @param dilution   稀释倍数
   * @param exaggerate 夸张倍数
   * @return
   */
  @RequestMapping(value = "getParticleFlowOfSlice")
  @ResponseBody
  public AjaxResult getParticleFlowOfSlice(@RequestParam("filePath") String filePath,
                                           int level,
                                           int dilution,
                                           int exaggerate) {
    try (NetcdfFile ncFile = NetcdfFile.open(filePath)) {
      FlowData uu = factorService.getParticleFlowDataOfFlowOfSlice(ncFile, level, UU, dilution, exaggerate);
      FlowData vv = factorService.getParticleFlowDataOfFlowOfSlice(ncFile, level, VV, dilution, exaggerate);
      List<Float> data = new ArrayList<>();
      for (int i = 0; i < uu.getData().size(); i++) {
        if (uu.getData().get(i) != null || vv.getData().get(i) != null) {
          if ((float) Arith.round(Math.sqrt(Math.pow(uu.getData().get(i), 2) + Math.pow(vv.getData().get(i), 2)), 4) > 150) {
          }
          data.add((float) Arith.round(Math.sqrt(Math.pow(uu.getData().get(i), 2) + Math.pow(vv.getData().get(i), 2)), 4));
        } else {
          data.add(0f);
        }
      }
      Object[] objects = {uu, vv, data};
      return AjaxResult.success(objects);
    } catch (Exception e) {
      e.printStackTrace();
      return AjaxResult.error("获取nc文件失败");
    }
  }

  /**
   * 从数据库中查询文件，并返回给前台画图
   *
   * @param filePath        文件路径
   * @param factorCondition 要素条件
   * @return
   */
  @RequestMapping(value = "/ncFileFactor")
  //@RepeatSubmit
//  @Log(title = "nc文件可视化（通过d3）", businessType = BusinessType.DRAW, isSaveResponseData = false)
  @ResponseBody
  public AjaxResult getNcFileFactor(@RequestParam("filePath") String filePath,
                                    FactorCondition factorCondition,
                                    @RequestParam(value = "time", required = false) Integer time) {
    return getNcData(filePath, factorCondition, time);
  }

  /**
   * 前台通过open按钮打开一个文件传递文件的文件名给后台
   * 后台通过路劲拼接，找到nc文件
   * 读取相应的参数，返回相应的数据给前台
   *
   * @param fileName        nc文件名
   * @param factorCondition 参数设置条件
   * @return
   */
  @RequestMapping(value = "getFactorByOpenFile")
//  @Log(title = "nc文件可视化", businessType = BusinessType.DRAW, isSaveResponseData = false)
  @ResponseBody
  public AjaxResult getFactorByOpenFile(@RequestParam("fileName") String fileName,
                                        FactorCondition factorCondition,
                                        @RequestParam(value = "time", required = false) Integer time) {
    String filePath = String.join(File.separator, applicationProperties.getNavData(), fileName);
    return getNcData(filePath, factorCondition, time);

  }

  /**
   * 通过打开按钮实现nc文件可视化
   * 通过打开图片的方式
   *
   * @param fileName        文件名
   * @param factorCondition 条件
   * @param fixedMin        设定的最小值
   * @param fixedMax        设定的最大值
   * @param colorType       颜色类型
   * @param time            时间
   * @param reverseFlag     图片是否翻转
   * @return
   */
  @RequestMapping(value = "getPictByOpen")
//  @Log(title = "nc文件可视化", businessType = BusinessType.DRAW, isSaveResponseData = false)
  public AjaxResult getPictByOpen(@RequestParam("fileName") String fileName,
                                  FactorCondition factorCondition,
                                  @RequestParam("fixedMin") float fixedMin,
                                  @RequestParam("fixedMax") float fixedMax,
                                  @RequestParam("colorType") String colorType,
                                  @RequestParam(value = "time", required = false) Integer time,
                                  @RequestParam(value = "reverseFlag", required = false, defaultValue = "false") boolean reverseFlag) {
    String filePath = String.join(File.separator, applicationProperties.getNavData(), fileName);
    return getPict(filePath, factorCondition, fixedMin, fixedMax, colorType, time, reverseFlag);

  }


  /**
   * 获取有经纬度限制的粒子流
   * 适用于只有总值和角度没有u分量和v分量情况
   * 现在只适用于浪数据
   *
   * @param filePath        nc文件绝对路径
   * @param factorCondition 要素条件
   * @return
   */
  @RequestMapping(value = "getParticleFlowOfWaveByLimit")
  @ResponseBody
//  @Log(title = "海浪粒子流可视化", businessType = BusinessType.DRAW, isSaveResponseData = false)
  public AjaxResult getParticleFlowOfWaveByLimit(@RequestParam("filePath") String filePath,
                                                 FactorCondition factorCondition,
                                                 @RequestParam(value = "time", required = false) Integer time,
                                                 int dilution,
                                                 int exaggerate) {
    try (NetcdfFile ncFile = NetcdfFile.open(filePath)) {
      FlowData uu = factorService.getParticleFlowDataOfWaveOfLimit(ncFile, factorCondition.getStartLon(), factorCondition.getEndLon()
          , factorCondition.getStartLat(), factorCondition.getEndLat(), 0, time, UU, dilution, exaggerate, false);
      FlowData vv = factorService.getParticleFlowDataOfWaveOfLimit(ncFile, factorCondition.getStartLon(), factorCondition.getEndLon()
          , factorCondition.getStartLat(), factorCondition.getEndLat(), 0, time, VV, dilution, exaggerate, false);
      List<Float> data = new ArrayList<>();
      for (int i = 0; i < uu.getData().size(); i++) {
        if (uu.getData().get(i) != null || vv.getData().get(i) != null) {
          data.add((float) Arith.round(Math.sqrt(Math.pow(uu.getData().get(i), 2) + Math.pow(vv.getData().get(i), 2)), 4));
        } else {
          data.add(0f);
        }
      }
      Object[] objects = {uu, vv, data};
      return AjaxResult.success(objects);
    } catch (Exception e) {
      e.printStackTrace();
      return AjaxResult.error("获取nc文件失败");
    }
  }

  /**
   * 获取固定路径D:/mybatase下的png图片信息
   * 包含文件名和base64位码
   *
   * @return
   */
  @RequestMapping("/getGlobePNG")
//  @Log(title = "获取固定文件夹下面的图片", businessType = BusinessType.DRAW, isSaveResponseData = false)
  @ResponseBody
  public AjaxResult getGlobePNG() {
    try {
      List<String> fileList = FileUtils.getFileList(applicationProperties.getSarPng());
      if (fileList != null) {
        List<PictFile> pictFiles = new ArrayList<>();
        for (String s : fileList) {
          if (s.contains(".png")) {
            pictFiles.add(ncPictService.getPictFile(s));
          }

        }
        return AjaxResult.success(pictFiles);
      }
      return AjaxResult.warn("没有相应文件");
    } catch (Exception e) {
      return AjaxResult.error("获取图片路径失败");
    }
  }


  /**
   * 获取nc数据，本controller使用
   * 为了代码结构简洁美观
   * 把所有数据都放到缓存里面，下次可以直接使用
   * 目前只是先画标量场会对矢量场进行缓存加载
   * 没有先矢量会对标量场进行缓存加载
   * 不是不能做，只是正常人应该都是先标量再矢量，显示标量场的时候加入矢量场缓存数据
   * 如果在显示矢量场的时候就缓存加载标量场，一定会延长矢量场显示的时间
   * 就是是否真的必要（逻辑操作问题，商量后可解决）
   *
   * @param filePath        nc文件路径
   * @param factorCondition 要素条件
   * @return
   */
  private AjaxResult getNcData(String filePath,
                               FactorCondition factorCondition,
                               Integer time) {
    try {
      if (factorCondition.getVariableName().equals(CURRENT)) {
        return AjaxResult.success("你请求的接口是流接口并不正确");
      }
//      factorService.getFactorForCache(filePath, factorCondition, time);
      NetcdfFile ncFile = NetcdfFile.open(filePath);

//      NetcdfFile ncFile = NetcdfFile.open(filePath);

    /*  d3画流
    ContourData<FlowGridData> flowData = eddyCharacterService.getFlowGridData(ncFile, new Float[]{factorCondition.getStartLon(),
              factorCondition.getEndLon()}, new Float[]{factorCondition.getStartLat(), factorCondition.getEndLat()},
          factorCondition.getLevel(), time);*/
      /*
       * 粒子流数据加到缓存中*/

//等会打开
      Map<String, NcData> ncDataOfLimitU = ncDao.getNcDataOfLimitFromVariable(ncFile, UU, new Float[]{factorCondition.getStartLon(), factorCondition.getEndLon()}, new Float[]{factorCondition.getStartLat(), factorCondition.getEndLat()}, factorCondition.getLevel(), time);
      Map<String, NcData> ncDataOfLimitV = ncDao.getNcDataOfLimitFromVariable(ncFile, VV, new Float[]{factorCondition.getStartLon(), factorCondition.getEndLon()}, new Float[]{factorCondition.getStartLat(), factorCondition.getEndLat()}, factorCondition.getLevel(), time);

      ContourData<FlowGridData> flowData1 = eddyCharacterService.getFlowGridDataFromDegree(ncFile, new Float[]{factorCondition.getStartLon(), factorCondition.getEndLon()},
          new Float[]{factorCondition.getStartLat(), factorCondition.getEndLat()}, factorCondition.getLevel(), time);

      ContourData<NcGridData> salt = factorService.getNcContourData(ncFile, "salt", new Float[]{factorCondition.getStartLon(), factorCondition.getEndLon()},
          new Float[]{factorCondition.getStartLat(), factorCondition.getEndLat()}, factorCondition.getLevel(), time);

      ContourData<NcGridData> temp = factorService.getNcContourData(ncFile, "temp", new Float[]{factorCondition.getStartLon(), factorCondition.getEndLon()},
          new Float[]{factorCondition.getStartLat(), factorCondition.getEndLat()}, factorCondition.getLevel(), time);

      ContourData<NcGridData> ssh = factorService.getNcContourData(ncFile, "ssh", new Float[]{factorCondition.getStartLon(), factorCondition.getEndLon()},
          new Float[]{factorCondition.getStartLat(), factorCondition.getEndLat()}, factorCondition.getLevel(), time);
//      factorService.getFactorForCache(filePath, factorCondition, time);
      return AjaxResult.success(factorService.getNcContourData(ncFile, factorCondition.getVariableName(), new Float[]{factorCondition.getStartLon(), factorCondition.getEndLon()},
          new Float[]{factorCondition.getStartLat(), factorCondition.getEndLat()}, factorCondition.getLevel(), time));

    } catch (Exception e) {
      e.printStackTrace();
      return AjaxResult.error("获取nc文件失败");
    }
  }

  /**
   * nc文件可视化通过图片进行可视化
   *
   * @param filePath        文件路径
   * @param factorCondition nc文件条件
   * @param fixedMin        设定的最小值
   * @param fixedMax        设定的最大值
   * @param colorType       颜色类型
   * @param time            时间
   * @param reverseFlag     是否翻转
   * @return
   */
  private AjaxResult getPict(@RequestParam("filePath") String filePath,
                             FactorCondition factorCondition,
                             @RequestParam("fixedMin") float fixedMin,
                             @RequestParam("fixedMax") float fixedMax,
                             @RequestParam("colorType") String colorType,
                             @RequestParam(value = "time", required = false) Integer time,
                             @RequestParam(value = "reverseFlag", required = false, defaultValue = "false") boolean reverseFlag) {
    System.out.println("filePath = " + filePath);
    try (NetcdfFile ncFile = NetcdfFile.open(filePath)) {
      // 如果获取的不是流数据使用获取单个数据
      if (!factorCondition.getVariableName().equals(CURRENTUV)) {
        return AjaxResult.success(factorService.getCommonFactorForPict(ncFile, factorCondition, fixedMin, fixedMax, colorType, time, reverseFlag));
      }
      //流数据
      //获取u和v数据要获取两次
      else if (factorCondition.getVariableName().equals(CURRENTUV)) {
        return AjaxResult.success(factorService.getCurrentFactorForPict(ncFile, factorCondition, fixedMin, fixedMax, colorType, time, reverseFlag));
      }
    } catch (Exception e) {
      e.printStackTrace();
    }
    return AjaxResult.error("生成失败");
  }

  /**
   * 获取时间段的播放数据将其放到缓存里面中
   *
   * @param filePath        想要放到缓存里面的文件路径
   * @param factorCondition 要素条件
   * @param realFilePath    真实想要的nc文件路径
   * @param dilution        稀释倍数
   * @param exaggerate      夸张指数
   * @param time            时间
   * @return
   */
  @RequestMapping("/getVideoFromTime")
//  @Log(title = "获取时间段的播放数据", businessType = BusinessType.DRAW, isSaveResponseData = false)
  public AjaxResult getVideoFromTime(@RequestParam("filePath") String[] filePath, FactorCondition factorCondition,
                                     @RequestParam("realFilePath") String realFilePath,
                                     @RequestParam(value = "dilution", required = false, defaultValue = "10") Integer dilution,
                                     @RequestParam(value = "exaggerate", required = false, defaultValue = "100") Integer exaggerate,
                                     @RequestParam(value = "time", required = false) Integer time) {
    try {
      factorService.getVideoFromTime(filePath, factorCondition, dilution, exaggerate, time);
      NetcdfFile ncFile = ncDao.getNcFile(realFilePath);
      if (CURRENTUV.equals(factorCondition.getVariableName())) {
        FlowData uu = factorService.getParticleFlowDataOfFlowByLimit(ncFile, factorCondition.getStartLon(), factorCondition.getEndLon(),
            factorCondition.getStartLat(), factorCondition.getEndLat(), factorCondition.getLevel(), UU, dilution, exaggerate, true, false);
        FlowData vv = factorService.getParticleFlowDataOfFlowByLimit(ncFile, factorCondition.getStartLon(), factorCondition.getEndLon(),
            factorCondition.getStartLat(), factorCondition.getEndLat(), factorCondition.getLevel(), VV, dilution, exaggerate, true, false);
        return AjaxResult.success(new Object[]{uu, vv});
      } else {
        return AjaxResult.success(factorService.getNcContourData(ncFile, factorCondition.getVariableName(), new Float[]{factorCondition.getStartLon(), factorCondition.getEndLon()},
            new Float[]{factorCondition.getStartLat(), factorCondition.getEndLat()}, factorCondition.getLevel(), time));
      }
    } catch (Exception e) {
      e.printStackTrace();
      return AjaxResult.error("获取数据失败由于:" + e.getMessage());
    }

  }


  /**
   * 获取单点数据
   * 如果只有一层返回一个数据
   * 否则是一个数组
   *
   * @param upload       查询对象
   * @param variableName 变量名
   * @param lon          经度
   * @param lat          纬度
   * @return
   */
  @RequestMapping("/getPointOfData")
  @ResponseBody
  public AjaxResult getPointOfData(Upload upload,
                                   @RequestParam("variableName") String variableName,
                                   @RequestParam("lon") Float lon,
                                   @RequestParam("lat") Float lat) {
    List<Upload> uploads = uploadService.selectFactorList(upload);
    try (NetcdfFile ncFile = NetcdfFile.open(uploads.get(0).getFilePath())) {
      NcRecord ncRecord = new NcDaoImpl().getData3DWithLimit(ncFile, variableName, new Float[]{lon, lon}, new Float[]{lat, lat});
      if (ncRecord.getData3D() != null) {
        return AjaxResult.success(ArrayUtils.flat3D(ncRecord.getData3D()));
      } else if (ncRecord.getData2D() != null) {
        return AjaxResult.success(ArrayUtils.flat2D(ncRecord.getData2D()));
      }
    } catch (Exception e) {
      e.printStackTrace();
      return AjaxResult.error("获取数据失败");
    }
    return AjaxResult.error("检查文件路径和条件");
  }

  /**
   * 绘制全球要素通过图片的方式
   * 使用线程池技术多线程并发生成图片
   * 可以降低资源消耗，提高响应速度，方便管理
   *
   * @param filePath        文件路径
   * @param factorCondition 要素条件
   * @param fixedMin        设定的最小值
   * @param fixedMax        设定的最大值
   * @param colorType       颜色类型
   * @param time            时间
   * @param reverseFlag     是否翻转
   * @return
   */
  @RequestMapping("/getGlobalPict")
  @ResponseBody
  public AjaxResult getGlobalPict(@RequestParam("filePath") String filePath,
                                  FactorCondition factorCondition,
                                  @RequestParam("fixedMin") float fixedMin,
                                  @RequestParam("fixedMax") float fixedMax,
                                  @RequestParam("colorType") String colorType,
                                  @RequestParam(value = "time", required = false) Integer time,
                                  @RequestParam(value = "reverseFlag", required = false, defaultValue = "false") boolean reverseFlag) {

    try (NetcdfFile ncFile = NetcdfFile.open(filePath)) {
      return AjaxResult.success(factorService.getGlobelPng(ncFile, factorCondition.getVariableName(), fixedMin, fixedMax, colorType, factorCondition.getLevel(), time, reverseFlag));
    } catch (Exception e) {
      e.printStackTrace();
      return AjaxResult.error("获取数据失败");
    }
  }

  /**
   * 绘制全球要素通过图片的方式（保存为文件png+info信息）
   * 使用线程池技术多线程并发生成图片
   * 可以降低资源消耗，提高响应速度，方便管理
   *
   * @param filePath    文件路径
   * @param fixedMin    设定的最小值
   * @param fixedMax    设定的最大值
   * @param colorType   颜色类型
   * @param time        时间
   * @param reverseFlag 是否翻转
   * @return 文件路径
   */
  @PostMapping("/getGlobalPictToFile")
  public AjaxResult getGlobalPictToFile(@RequestParam("filePath") String filePath,
                                        @RequestParam("outFilePath") String outFilePath,
                                        @RequestParam("variableName") String variableName,
                                        @RequestParam("level") Integer level,
                                        @RequestParam(value = "fixedMin", defaultValue = "-2") float fixedMin,
                                        @RequestParam(value = "fixedMax", defaultValue = "31") float fixedMax,
                                        @RequestParam(value = "colorType", defaultValue = "rainbow") String colorType,
                                        @RequestParam(value = "time", required = false) Integer time,
                                        @RequestParam(value = "reverseFlag", required = false, defaultValue = "false") boolean reverseFlag) {

    try (NetcdfFile ncFile = NetcdfFile.open(filePath)) {

      return AjaxResult.success(factorService.getGlobelPngToFile(ncFile, outFilePath, variableName, fixedMin, fixedMax, colorType, level, time, reverseFlag));

//      return AjaxResult.success(factorService.getGlobelPng(ncFile, variableName, fixedMin, fixedMax, colorType, level, time, reverseFlag));

    } catch (Exception e) {
      e.printStackTrace();
      return AjaxResult.error("获取数据失败");
    }
  }


  /**
   * 预报数据
   * 绘制全球要素通过图片的方式（保存为文件png+info信息）从今天开始，往后index天
   * 使用线程池技术多线程并发生成图片
   * 可以降低资源消耗，提高响应速度，方便管理
   *
   * @param index       共处理多少天的
   * @param reverseFlag 是否翻转
   * @return 文件路径
   */
  @PostMapping("/getGlobalPictToFileList")
  public AjaxResult getGlobalPictToFileList(@RequestParam("index") Integer index,
                                            @RequestParam(value = "colorType", defaultValue = "rainbow") String colorType,
                                            @RequestParam(value = "reverseFlag", required = false, defaultValue = "false") boolean reverseFlag) throws IOException, InvalidRangeException, ExecutionException, InterruptedException {
    Date today = DateUtils.parseDate(DateUtils.getDate());
    String todayString = DateUtils.parseDateToStr("yyyyMMdd", today);
    String outFilePath = "D:\\mydatabase\\forecastimage\\" + todayString + "\\";
    int sum = 0;
    for (int i = 0; i < index.intValue(); i++) {
      Date day = DateUtils.addDays(today, i);
      String time = DateUtils.parseDateToStr("yyyyMMdd", day);
      String filePath = "D:\\mydatabase\\forecastdata\\" + todayString + "\\" + time + "_thetao.nc";
      outFilePath = "D:\\mydatabase\\temperature\\" + todayString + "\\" + "png" + time + "00_sst";

      NetcdfFile ncFile = NetcdfFile.open(filePath);
      factorService.getGlobelPngToFile(ncFile, outFilePath, "thetao", -2, 31, colorType, 0, Integer.valueOf(time), reverseFlag);
      sum++;

      filePath = "D:\\mydatabase\\forecastdata\\" + todayString + "\\" + time + "_so.nc";
      outFilePath = "D:\\mydatabase\\salinity\\" + todayString + "\\" + "png" + time + "00_so";

      ncFile = NetcdfFile.open(filePath);
      factorService.getGlobelPngToFile(ncFile, outFilePath, "so", 0, 40, colorType, 0, Integer.valueOf(time), reverseFlag);
      sum++;

    }
    return AjaxResult.success("共生成png和info文件" + sum + "个，文件路径为：" + outFilePath);
  }

  /**
   * 流程预报数据稀释生成nc
   *
   * @param index
   * @return
   * @throws IOException
   * @throws InvalidRangeException
   */
  @PostMapping("getCurToNc")
  public AjaxResult getCurToNc(@RequestParam("index") Integer index) throws IOException, InvalidRangeException {
    Date today = DateUtils.parseDate(DateUtils.getDate());
    String todayString = DateUtils.parseDateToStr("yyyyMMdd", today);

    int sum = 0;
    for (int i = 0; i < index.intValue(); i++) {
      Date day = DateUtils.addDays(today, i);
      String time = DateUtils.parseDateToStr("yyyyMMdd", day);
      String filePath = "D:\\mydatabase\\forecastdata\\" + todayString + "\\" + time + "_cur.nc";
      String outFilePath = "D:\\mydatabase\\flowField\\" + todayString + "\\" + time + "00_cur.nc";
      NetcdfFile ncFile = NetcdfFile.open(filePath);
      factorService.getCurToNc(ncFile, outFilePath, Integer.valueOf(time));
      sum++;
    }

    return AjaxResult.success("共生成NC文件" + sum + "个");
  }

  /**
   * 海洋nc文件上传时，同时生成png图片
   */
  @ResponseBody
  @RequestMapping("/drawPngByNc")
  public AjaxResult drawPngByNc(@RequestParam(value = "fileId") Integer fileId) throws IOException, InvalidRangeException, ExecutionException, InterruptedException {
    try {

      Upload ncUpload = uploadService.selectUploadByFileId(fileId);
      String ncFilePath = memoryDeviceService.selectSysMemoryDeviceById(ncUpload.getFileMemoryId()).getSysMemoryDevice()
          + dataSetService.selectSysDataSetById(ncUpload.getFileDataSetId()).getDataSetDevice() + ncUpload.getFilePath();
      String pngPath = memoryDeviceService.selectSysMemoryDeviceById(ncUpload.getFileMemoryId()).getSysMemoryDevice()
          + dataSetService.selectSysDataSetById(ncUpload.getFileDataSetId()).getDataSetDevice() + ncUpload.getFilePngPath();
      if (ncUpload.getFilePngPath() != null && new File(pngPath).exists()) {
        return AjaxResult.success("缩略图已存在，请勿重新生成");
      }
      File ncFile = new File(ncFilePath);
      String fileDir = ncFile.getParent() + File.separator;
      String fileName = ncFile.getName();
      String fileShortPath = ncUpload.getFilePath().split(fileName)[0];
      String time = DateUtils.parseDateToStr("yyyyMMdd", ncUpload.getFileTime());
      NetcdfFile nc = NetcdfFile.open(ncFilePath);
      Upload updateUpload = new Upload();
      updateUpload.setFileId(fileId);

      if (ncUpload.getVariableList().indexOf("ssh") > -1) {
        String outPngPath = fileDir + "png" + time + "00_ssh";
        factorService.getGlobelPngToFile(nc, outPngPath, "ssh", -2, 1.5f, "rainbow", 0, Integer.valueOf(time), false);
        updateUpload.setFilePngPath(fileShortPath + "png" + time + "00_ssh" + ".png");
        uploadService.updateUpload(updateUpload);
        return AjaxResult.success("已成功生成");
      } else if (ncUpload.getVariableList().indexOf("salt") > -1) {
        String outPngPath = fileDir + "png" + time + "00_so";
        factorService.getGlobelPngToFile(nc, outPngPath, "so", 0, 40, "rainbow", 0, Integer.valueOf(time), false);
        updateUpload.setFilePngPath(fileShortPath + "png" + time + "00_so" + ".png");
        uploadService.updateUpload(updateUpload);
        return AjaxResult.success("已成功生成");
      } else if (ncUpload.getVariableList().indexOf("temp") > -1) {
        String outPngPath = fileDir + "png" + time + "00_sst";
        factorService.getGlobelPngToFile(nc, outPngPath, "thetao", -2, 31, "rainbow", 0, Integer.valueOf(time), false);
        updateUpload.setFilePngPath(fileShortPath + "png" + time + "00_sst" + ".png");
        uploadService.updateUpload(updateUpload);
        return AjaxResult.success("已成功生成");
      }

      return AjaxResult.error("未找到可生成缩略图的变量");
    } catch (Exception e) {
      return AjaxResult.error("未生成成功" + e);
    }
  }


//  /**
//   * 对某一要素画等值线
//   *
//   * @param
//   */
//  @RequestMapping("/getIsoline")
//  @ResponseBody
//  public AjaxResult getIsoline(@RequestParam("filePath") String filePath,
//                               @RequestParam("element") String element,
//                               @RequestParam("depthIndex") int depthIndex,
//                               @RequestParam("timeIndex") int timeIndex) throws IOException {
//    Map<String, Object> resMap = new HashMap<String, Object>();
//    //获取NC的数据
//    Map map = getIsolineNcData(filePath, element, depthIndex, timeIndex);
//    if (map == null || map.size() == 0) {
//      return AjaxResult.success(resMap);
//    }
//    //等值线等值面间隔,间隔越小:过渡越均匀,性能消耗越大,响应越慢
//    double[] dataInterval = new double[]{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
//        16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 35};
//    String strGeoJson = nc2EquiSurface(map, dataInterval);
//    resMap.put("geojson", strGeoJson);
//    resMap.put("dataArr", map.get("eleData"));
//    return AjaxResult.success(resMap);
//  }

}
